package net.oschina.bilbodai.common.beanutil.bean.code;

import net.oschina.bilbodai.common.beanutil.bean.core.PropertyDumpInfo;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.IFNONNULL;

/**
 * @author daimao  Date: 16/5/28 Time: 下午4:38
 * @version $Id$
 */
public abstract class DumpOverrideAwareApplier extends GetterSetterCodeApplier {

    public DumpOverrideAwareApplier(PropertyDumpInfo dumpInfo) {
        super(dumpInfo);
    }

    /**
     * 操作: 源字段值入栈,将栈值通过调用目标的setter放入目标字段
     * <pre>
     *          Locals:    0            1            2            3             4
     *                  this     (obj)src   (obj)target     srcCast     targetCast
     *          Stack:   empty
     *
     * </pre>
     *
     * @param mv MethodVisitor
     */
    protected abstract void doApply(MethodVisitor mv);

    @Override
    public void apply(MethodVisitor mv) {
        Label ifTargetNotNullLabel = null;
        if (!dumpInfo.isDumpOverride()) {
            loadTargetCastPropertyOntoStack(mv);
            ifTargetNotNullLabel = new Label();
            mv.visitJumpInsn(IFNONNULL, ifTargetNotNullLabel);
        }

        doApply(mv);

        if (!dumpInfo.isDumpOverride()) {
            mv.visitLabel(ifTargetNotNullLabel);
        }
    }
}